NEWTON documentation - NEWTON documentation - NEWTON documentation
______________________________________________________________________________

protoLlamaTalk
by Jim Schram
Copyright 1994-1995 by Apple Computer, Inc. All rights reserved
Version 2.0a1 - Nov 14, 1995


What is LlamaTalk?
1) Oral grunts forming a system of communication between two or more Llamas.
2) An interrogative shouted by small children when grunted at by Llamas.
3) A client-server protocol used for Newton-to-Macintosh communication.


The LlamaTalk protocol is a two-way context-free framed transaction protocol
used for communication between a Newton and a Macintosh.  The protocol is
based on a reliable, error-free delivery system such as ADSP or MNP.  This
document will describe the basic transaction delivery system for simple,
unacknowledged transaction packets.  The reader is encouraged to implement
higher-level protocols as appropriate.

A LlamaTalk transaction packet is a variable non-zero sized binary object
containing context-independent data.  The transaction is assembled as a
stream; data is written serially into an expanding buffer until complete,
and then sent as a single LlamaTalk packet.  Due to the limited amount of
memory available in the Newton, individual transactions should therefore be
kept to a reasonable size.

Currently only a simple transport packet type is implemented.  However, the
protocol allows for future enhancements such as encryption, control packets,
and message priority.  Compression is assumed to be handled by the
underlying transport (for instance, MNP).

LlamaTalk is implemented on the Newton as a user proto view and is designed
to be placed somewhere on the base application view (or other view) which
will perform all connection-related activities.  The connection and its
settings are maintained only while the view is open, so it is unwise to
place the proto view on a form in which :RedoChildren() or similar functions
may be called.

The basic connection is established as follows:

// the view is operational only after it has been opened
   view:Open();

// view:MSetProtocol('MNP);
// view:MSetAddress(nil);
   view:MSetProtocol('ADSP);
   view:MSetAddress("Echo Server:EchoLlama@*");

// local err := view:MConnectAsync();
   local err := view:MConnect();
   if err then view:Close();

To input data, you need an idle loop which polls view:MRead() or a script
slot named MLlamaTalk_InputScript which will be called when input data is
available.

To write data:

// you must bracket your writes as follows
   view:MBeginTransaction();
   view:MWriteObject("Hello");
   view:MWriteObject("How are you?");
   view:MEndTransaction();

Call view:MDisconnect() and/or view:Close() to close the connection.

The view, when visible, blinks its I/O status "light" to indicate that data
is being sent and received.  Solid black means sending, gray means
receiving, white means idle, and white with an "X" means not connected.  If
you do not wish the view to provide visual feedback, simply call view:Hide()
and/or modify the view's coordinates as appropriate after opening the view.

==========

The following files are included in the Newton LlamaTalk package:

protoLlamaTalk              Main protocol source and data structures.

LlamaTalk                   Project file for the sample app.
LlamaTalk.rsrc              Contains extras drawer icon for the sample app.
LlamaTalkMain.t             Application base view for the sample app.
Project Data                Constants for the sample app.

LlamaTalk.pkg               The sample application package.


==========  Public View Methods

The following view methods are to be used when interacting with the
LlamaTalk proto.  All other fields and methods are considered private
and are subject to change in future implementations.

-----------

view:MConnect() --> nil, integer

Returns nil if successful, or an integer error code.

Opens a connection (if not already open) using the current address and
protocol.  Disables poweroff.

Note:  The default protocol is ADSP and the default address is nil.  You
should call view:MSetAddress(address) before connecting.  The MNP protocol
does not require an address (so pass nil in that case).

-----------

view:MConnectAsync() --> nil, integer

Same as view:MConnect() but asynchronous, thus giving the user a chance
to cancel the connect attempt.

-----------

view:MDisconnect() --> nil

Closes the connection (if open) and clears all pending input and output
data.  Enables poweroff.

-----------

view:MGetState() --> integer

This method checks the state of the endpoint and returns one of the
following integers:  -666 = kLlamaTalkIllegalOperationError, -1 = not
connected, 0 = uninitialized, 1 = unbound, 2 = idle, 3 = outgoing connection
pending, 4 = incoming connection pending, 5 = data transfer, 6 = outgoing
release pending, 7= incoming release pending, 8 = state is changing

Note:  These states relate to the endpoint and not the state machine
states of protoLlamaTalk which are stored in the fLlamaTalkState
application base view slot (a required slot of any application which
uses the protoLlamaTalk proto).

-----------

view:MRead() --> nil, binary

Returns nil if no transaction data was available, or a binary object
comprising the entire transaction taken from the input queue.

This method is designed to be called in place of the optional parent
:MLlamaTalk_InputScript() method (see "Optional View Methods" below).  This
allows a separate polling system to be used in place of the normal LlamaTalk
input script trigger.

-----------

view:MBeginTransaction() --> nil, true

Returns true if transaction can be started, nil if it can not.

Begins an output transaction.  Only one transaction may be active at a time.

-----------

view:MAbortTransaction() --> nil

Abort the transaction in progress.  Transactions can only be aborted while
they are being assembled, not after view:MEndTransaction() is called.

-----------

view:MWriteObject(data) --> nil, binary
    data = nil, true, character, integer, real, unicode string, binary

Returns nil if passed an unsupported data type, or the current transaction
stream object.

Used to assemble the transaction.  The data type is examined, flattened, and
written into the transaction buffer with the necessary tokens to allow a
stream-read of the transaction entry by the receiver.  The format for each
translated data type is as follows:

SOURCE TYPE   TRANSLATED FORMAT
nil        ->  0x00
true       ->  0x01
character  ->  0x02, 1-byte unicode to ASCII translation
integer    ->  0x03, 4-byte singed long integer in MSB->LSB format
real       ->  0x04, 1-byte length, N-bytes of real as pascal-format string
string     ->  0x05, 2-byte length in MSB->LSB format, N-bytes of string
binary     ->  0x06, 4-byte length in MSB->LSB format, N-bytes of bytes

-----------

view:MEndTransaction()  --> nil

Completes the current transaction assembly and inserts it into the output
queue for transmission.

-----------

view:MCountPendingInputTransactions() --> integer

Returns the number of input transactions which have arrived and are awaiting
processing.

-----------

view:MCountPendingOutputTransactions() --> integer

Returns the number of output transactions which are pending transmission.

-----------

view:MAbortPendingTransactions() --> nil

Aborts all pending input and output transactions.  Does not affect a
transaction currently being assembled for output, or a transaction currently
being received.

-----------

view:MSetAddress(address) --> nil, frame
    address = nil, string, or frame

Returns nil, an ADSP address frame, or other address frame.

Set the connection address to be used during :MConnect().

If address is nil, no address will be used during connection. MNP does not
require an address, so you may pass nil when using this protocol.

If address is a string, it must describe the ADSP remote name, remote type,
and remote zone in which to look as follows:  "name:type@zone"  (you may use
the asterisk "*" to indicate the current zone to which the Newton is
connected).

If address is a frame, it will be passed to the endpoint during connection. 
This is used primarily by foreign endpoint configurations.

The address can be set anytime after the view is opened and before a
connection is established.

-----------

view:MGetAddress()  --> nil, string, frame

Return the current address to which connections will be established.  
See view:MSetAddress(address) for more information.

-----------

view:MSetProtocol(protocol) --> nil, frame
    protocol = 'ADSP, 'MNP, or a LlamaTalk config frame

Returns nil for unsupported protocols, or a LlamaTalk config frame.

Set the protocol type to be used for communications.  Currently only the
symbols 'ADSP and 'MNP are supported, however, you may instead pass a
LlamaTalk config frame to use another endpoint.  This frame must specify a
reliable error free protocol and follow the LlamaTalk endpoint config frame
requirements.

-----------

view:MSetQuietDisconnect(quiet) --> nil, true
    quiet = nil, true

If quiet is true, a dropped connection will NOT be considered an error. This
should only be set when an "agreed to disconnect" stage of a higher-level
protocol has been reached, otherwise the disconnect will be detected and
treated as unexpected.

-----------

view:MIsQuietDisconnect()   --> nil, true

Returns true if disconnects will go unreported, nil otherwise.

-----------

view:MIsConnected() --> nil, true

Returns true if connected, nil otherwise.

-----------

view:MIsConnecting() --> nil, true

Returns true if a connect is in-progress, nil otherwise.

-----------

view:MIsOpen()  --> nil, true

Returns true if view is open, nil otherwise.

-----------

view:MIsVisible()   --> nil, true

Returns true if view is visible, nil otherwise.

-----------

view:MToggle()  --> nil

If the view is visible, it will be hidden, or if invisible, it will be
shown.


=============  Optional View Methods

The following view methods are designed as optional methods of a parent
view, and are called using the :? syntax from the LlamaTalk proto via
proto/parent inheritance.

-----------

view:MLlamaTalk_StdError(message, error) --> void
    message = string error message
    error = integer error code

This method is called in response to an endpoint exception, such as "Could
not connect." or "Port already in use?".  The return result is ignored.

-----------

view:MLlamaTalk_InputScript(data) --> void
    data = binary transaction data

This method is called in response to an incoming transaction.  The data is a
binary object comprising the entire transaction.  The return result is
ignored.

-----------

view:MLlamaTalk_StateChanged() --> void

This method is called whenever protoLlamaTalk changes its connection state.
It is designed as a notification to the application, giving the app a
chance to react to the state change (e.g. it can redraw buttons, update a
progress message, save data, etc.)


=============  What's New?

2.0a1

Complete rewrite to use protoBasicEndpoint.  LlamaTalk is now Newton OS 2.x specific.

Added passive connection support for both ADSP and MNP (single connection).

Made the MLlamaTalk_InputScript method a little smarter.  It now understands how
to display received information from both the LlamaTalkEchoApp and another Newton
running the LlamaTalk sample.

Now uses one VBO per input transaction (rather than a binary object in the
NewtonScript heap) to allow very large transaction objects to be handled.  *** Due
to a bug in the comm scripting interface of protoBasicEndpoint, the direct binary
target form of input is NOT used in this sample.  Instead data is received in 512-byte
chunks and programmatically streamed into the VBO as a temporary workaround. ***

Removed MWrite method.  The MWriteObject method no longer returns binary form of item.

Now uses one VBO per write transaction (rather than a queue of individual transaction
data elements) via a simple reusable VBO stream object.

Now uses RegPowerOff handler which will prevent the unit from idle sleeping while
a connection is active, yet the user can hit the power switch (or the batteries
can run low) to make the unit disconnect and sleep immediately.

Now uses AddDeferredSend rather than AddDeferredAction in MEndPointExceptionHandler.

Now calls MakeAppleTalkOption to create the protoBasicEndpoint ADSP address option
rather than constructing it via a hard-coded template.

Added MProtoClone method to demonstrate a method of creating efficient modifiable
protoBasicEndpoint specs which use _proto inheritance.

Modifications for NTK 1.6
DeclareGlobalFn on LT_PRINT to suppress global function warnings during NTK compilation.
DefGlobalFn on LT_PRINT for runtime use of LT_PRINT (no more functions.LT_PRINT hack).

-----------

1.0a8

Modifications for NTK 1.5
evaluate slot for app title, now uses kAppName & kAppSymbol from NTK dialog


-----------

1.0a7

Removed the power-off patch code.  Now any MP110 v1.3 (344052) user must
also install the "MP110 Power Off Update.pkg" bug fix package.  See the
associated REAME file for details.

Added MLlamaTalk_StateChanged(), MIsConnecting(), MConnectAsync() methods.

Now requires a slot in the application base view called fLlamaTalkState.
This must be a nil eval slot after compilation.  It is used to manage
the connection states of protoLlamaTalk.  Basically just define it and
forget it.  protoLlamaTalk won't work without it, and its values aren't
meaningful to anyone besides protoLlamaTalk.

-----------

1.0a6

Initial release as PIE DTS Sample Code.

-----------

No part of this document or the software described in it may be altered in
any way and subsequently distributed as original material without prior
written permission of Apple Computer, Inc.  No licenses, express or implied,
are granted with respect to any of the technology described therein.  This
document and the accompanying software are intended to assist application
developers to develop applications only for licensed Newton platforms. Apple
makes no warranty or representation either express or implied of the
aforementioned technology with respect to the quality, accuracy,
merchantability, or fitness for a particular purpose.  As a result, this
material is distributed "as is" and you, the reader, are assuming the entire
risk as to its quality and accuracy.  It's sample code, darn it.
